package com.uduemc.biso.node.web.api.design.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.uduemc.biso.core.extities.center.Host;
import com.uduemc.biso.core.extities.center.Site;
import com.uduemc.biso.core.utils.JsonResult;
import com.uduemc.biso.node.core.common.entities.SiteBasic;
import com.uduemc.biso.node.core.common.entities.SiteConfig;
import com.uduemc.biso.node.core.common.entities.sitebasic.AccessDevice;
import com.uduemc.biso.node.core.node.utils.PatternUriUtil;
import com.uduemc.biso.node.web.api.component.SiteHolder;
import com.uduemc.biso.node.web.api.component.SpringContextUtils;
import com.uduemc.biso.node.web.api.config.SpringContextUtil;
import com.uduemc.biso.node.web.api.design.service.DSiteService;
import com.uduemc.biso.node.web.api.service.HostService;
import com.uduemc.biso.node.web.api.service.SiteService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class DHostInterceptor implements HandlerInterceptor {

	private static final Logger logger = LoggerFactory.getLogger(DHostInterceptor.class);

	@Resource
	private SiteHolder siteHolder;

	@Resource
	private SpringContextUtil springContextUtil;

	@Resource
	private ObjectMapper objectMapper;

	/**
	 * 通过 requestURI 获取 hostId、siteId 后获取对应的数据并保存至 ThreadLocal 中
	 * 并截取与站点端一致的页面URI路径后进行下一个拦截器
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		HostService hostServiceImpl = SpringContextUtils.getBean("hostServiceImpl", HostService.class);
		SiteService siteServiceImpl = SpringContextUtils.getBean("siteServiceImpl", SiteService.class);
		DSiteService dSiteServiceImpl = SpringContextUtils.getBean("dSiteServiceImpl", DSiteService.class);

		// /api/design/ea43241506e7d6fbec4be0c6e43aae18/ff70dd7206521e6da10ee0b59074bd53/[device]/index.html
		String requestURI = request.getRequestURI();
		if (springContextUtil.local()) {
			String substring = requestURI.substring(requestURI.lastIndexOf("/") + 1);
			PathMatcher pathMatcher = new AntPathMatcher();
			if (pathMatcher.match("backend.*.hot-update.js.map", substring)) {
				return true;
			}
		}
		PatternUriUtil patternUri = new PatternUriUtil(requestURI);
		boolean matche = patternUri.matche();
		if (!matche) {
			// 给予一个403页面
			logger.error("patternUri.matche(); 匹配失败！ requestURI: " + requestURI);
			forbidden(response,JsonResult.illegal());
			return false;
		}

		String enHostId = patternUri.getEnHostId();
		String enSiteId = patternUri.getEnSiteId();
		String siteUri = patternUri.getSiteUri();

		// 通过传递的参数进行识别获取当前设备
		AccessDevice device = null;
		if (request.getParameter("device") == null) {
			device = AccessDevice.PC;
		} else {
			if (request.getParameter("device").toLowerCase().equals("pc")) {
				device = AccessDevice.PC;
			} else if (request.getParameter("device").toLowerCase().equals("mp")) {
				device = AccessDevice.MP;
			} else if (request.getParameter("device").toLowerCase().equals("pad")) {
				device = AccessDevice.PAD;
			} else {
				logger.error("request.getParameter(\"device\"); 匹配失败！ request.getParameter(\"device\"): "
						+ request.getParameter("device"));
				forbidden(response,JsonResult.illegal());
				return false;
			}
		}

		// 获取 hostId、siteId、siteUri 基础信息
		SiteBasic siteBasic = null;
		try {
			siteBasic = SiteBasic.getSiteBasic(enHostId, enSiteId, device, siteUri);
		} catch (Exception e) {
			logger.error(e.getMessage());
		}

		if (siteBasic == null) {
			// 给予一个403页面
			logger.error("未能获取 hostId、siteId以及 siteUri数据！");
			forbidden(response,JsonResult.illegal());
			return false;
		}

		// 通过 SiteBasic 获取 host、site 数据
		Host host = hostServiceImpl.getInfoById(siteBasic.getHostId());
		if (host == null) {
			// 给予一个403页面
			logger.error("未能获取 Host 数据！");
			forbidden(response,JsonResult.illegal());
			return false;
		}
		Site site = siteServiceImpl.getInfoById(siteBasic.getHostId(), siteBasic.getSiteId());
		if (site == null) {
			// 给予一个403页面
			logger.error("未能获取 Site 数据！");
			forbidden(response,JsonResult.illegal());
			return false;
		}
		// 在获取 SiteConfig 数据
		SiteConfig siteConfig = null;
		try {
			siteConfig = dSiteServiceImpl.getSiteConfigByHostSiteId(siteBasic.getHostId(), siteBasic.getSiteId());
		} catch (IOException e) {
		}
		if (siteConfig == null) {
			// 给予一个403页面
			logger.error("未能获取 SiteConfig 数据！");
			forbidden(response,JsonResult.illegal());
			return false;
		}

		// 将 Host、Site 数据存入 SiteHolder 中
		siteHolder.add(host).add(site).add(siteConfig).add(siteBasic).add(request);
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		logger.info("siteHolder.getHost(); " + siteHolder.getHost());
		logger.info("siteHolder.getSite(); " + siteHolder.getSite());
		logger.info("siteHolder.getSiteConfig(); " + siteHolder.getSiteConfig());
		logger.info("siteHolder.getSiteBasic(); " + siteHolder.getSiteBasic());
		logger.info("siteHolder.getSitePage(); " + siteHolder.getSitePage());
		logger.info("siteHolder.remove(); ");
		siteHolder.remove();
	}

	protected void forbidden(HttpServletResponse response, JsonResult jsonResult) throws IOException {
		response.setStatus(HttpStatus.FORBIDDEN.value());
		response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
		response.getWriter().print(objectMapper.writeValueAsString(jsonResult));
	}

}
